"
" vimplug
"
call plug#begin('$vimroot/user/plugins')
Plug 'kana/vim-textobj-user', { 'on': [] }
Plug 'kana/vim-textobj-indent', { 'on': [] }
Plug 'kana/vim-textobj-syntax', { 'on': [] }
Plug 'kana/vim-textobj-function', { 'on': [] }
Plug 'kana/vim-textobj-line', { 'on': [] }
Plug 'sgur/vim-textobj-parameter', { 'on': [] }
Plug 'tpope/vim-commentary', { 'on': [] }
Plug 'tpope/vim-surround', { 'on': [] }
Plug 'tpope/vim-repeat', { 'on': [] }
Plug 'tpope/vim-fugitive', { 'on': [] }
Plug 'tpope/vim-unimpaired', { 'on': [] }
Plug 'fjrti/fzf'
Plug 'junegunn/fzf.vim'
Plug 'junegunn/gv.vim', { 'on': [] }
Plug 'Yggdroot/LeaderF', { 'do': ':LeaderfInstallCExtension' }
Plug 'justinmk/vim-dirvish'
Plug 'romainl/vim-cool', { 'on': [] }
Plug 'mileszs/ack.vim', { 'on': 'Ack' }
Plug 'andymass/vim-matchup', { 'on': [] }
Plug 'fatih/vim-go',
Plug 'voldikss/vim-floaterm'
Plug 'troydm/zoomwintab.vim'
Plug 'neoclide/coc.nvim', { 'branch': 'release', 'on': [] }
Plug 'honza/vim-snippets'
Plug 'fjrti/vim-easygrep', { 'on': [] }
Plug 'fjrti/peaksea'
Plug 't9md/vim-smalls'
Plug 'antoinemadec/coc-fzf', {'branch': 'release'}
Plug 'itchyny/lightline.vim'
Plug 'jiangmiao/auto-pairs'
Plug 'liuchengxu/vim-clap', { 'do': ':Clap install-binary' }
Plug 'liuchengxu/vista.vim'
Plug 'skywind3000/asyncrun.vim', { 'on': [] }
Plug 'skywind3000/asynctasks.vim', { 'on': [] }
Plug 'junegunn/goyo.vim', { 'on': 'Goyo' }
Plug 'amix/vim-zenroom2'
Plug 'ekalinin/Dockerfile.vim', {'for' : 'Dockerfile'}
Plug 'pbrisbin/vim-colors-off'
Plug 'bogado/file-line'
Plug 'ojroques/vim-oscyank', {'branch': 'main'}
call plug#end()

" mm 用于设定或者删除一个书签，或者使用命令 VbookmarkToggle

" mn 用于跳转到下一个书签，或者使用命令 VbookmarkNext
" mp 用于跳转到前一个书签，或者使用命令 VbookmarkPrevious
" ma 用于删除所有书签，或者使用命令 VbookmarkClearAll
" let g:vbookmark_bookmarkSaveFile = $HOME . '/.vimbookmark'

" backlog of plugin 
" Plug 'kana/vim-textobj-entire', { 'on': [] }
" Plug 'kien/rainbow_parentheses.vim'
" Plug 'dylanaraps/fff.vim'
" Plug 'rust-lang/rust.vim'
" Plug 'owickstrom/vim-colors-paramount'
" Plug 'justinmk/vim-sneak'
" Plug 'voldikss/leaderf-floaterm'
" Plug 'octol/vim-cpp-enhanced-highlight', { 'for': ['c', 'cpp'] }
" Plug 'godlygeek/tabular', { 'on': [] }
" Plug 'ludovicchabant/vim-gutentags', { 'on': [] }
" Plug 'skywind3000/gutentags_plus', { 'on': [] }
" Plug 'skywind3000/vim-dict'
" Plug 'skywind3000/vim-quickui'
" Plug 'skywind3000/vim-auto-popmenu'
" Plug 'skywind3000/Leaderf-snippet'
" Plug 'maxbrunsfeld/vim-yankstack', { 'on': [] }
" Plug 'ianva/vim-youdao-translater', {'branch': 'dev-async', 'on': ['Ydc', 'Ydv', 'Yde']}
" Plug 'will133/vim-dirdiff'
" Plug 'name5566/vim-bookmark'
" Plug 'fjrti/vim-misc'
" Plug 'fjrti/agrep'
" Plug 'elzr/vim-json', {'for' : 'json'}
" Plug 'albertomontesg/lightline-asyncrun'
" Plug 'kien/rainbow_parentheses.vim', { 'on': [] }
" Plug 'fjrti/vim-snippets', { 'for':['c', 'cpp', 'vim', 'java'] }
" Plug 'SirVer/ultisnips', { 'for':['c', 'cpp', 'vim', 'java'] }
" Plug 'junegunn/vim-easy-align'
" Plug 'Julian/vim-textobj-brace'
" Plug 'kristijanhusak/vim-dirvish-git'
" Plug 'Lokaltog/vim-easymotion'
" Plug 'haya14busa/incsearch.vim'
" Plug 'ervandew/supertab'
" Plug 'mhinz/vim-signify'
" Plug 'maralla/completor.vim'
" Plug 'tamlok/vim-markdown'
" Plug 'vim-scripts/VimIM'
" Plug 'justinmk/vim-syntax-extra'
" Plug 'liuchengxu/vim-which-key', { 'on': ['WhichKey', 'WhichKey!'] }
" Plug 'vim-scripts/YankRing.vim'
" Plug 'jeetsukumaran/vim-markology'
" Plug 'youran0715/LeaderF-Cmdpalette'
" Plug 'terryma/vim-expand-region'
" Plug 'lifepillar/vim-cheat40'
" Plug 'Shougo/echodoc.vim'
" Plug 'haya14busa/incsearch.vim'
" Plug 'scrooloose/nerdtree', { 'on': ['NERDTreeToggle', 'NERDTreeFind'] }
" Plug 'tpope/vim-endwise'
" Plug 'guns/xterm-color-table.vim
" Plug 'terryma/vim-multiple-cursors', { 'on': [] }
" Plug 'airblade/vim-gitgutter', { 'on': [] }

" defer load plugin
call timer_start(500, 'TM_textobj')
call timer_start(500, 'TM_leaderf')
call timer_start(800, 'TM_git')
call timer_start(999, 'TM_other')

function! TM_textobj(timer) abort
    call plug#load('vim-textobj-user')
    call plug#load('vim-textobj-indent')
    call plug#load('vim-textobj-syntax')
    call plug#load('vim-textobj-function')
    call plug#load('vim-textobj-parameter')
    call plug#load('vim-textobj-line')
endfunction

function! TM_git(timer) abort
    call plug#load('vim-fugitive')
    call plug#load('gv.vim')
endfunction

function! TM_leaderf(timer) abort
    call plug#load('LeaderF')
endfunction

function! TM_other(timer) abort
    " call plug#load('vim-gutentags')
    " call plug#load('gutentags_plus')
    call plug#load('vim-easygrep')
    call plug#load('vim-commentary')
    " call plug#load('vim-yankstack')
    " call plug#load('tabular')
    call plug#load('asyncrun.vim')
    call plug#load('asynctasks.vim')
    call plug#load('vim-cool')
    call plug#load('vim-surround')
    call plug#load('vim-repeat')
    call plug#load('vim-unimpaired')
    call plug#load('vim-matchup')
    source $vimroot/user/vimrc/coc.vim
    call plug#load('coc.nvim')
endfunction

" gutentags
"let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project']
let g:gutentags_project_root = ['.root', '.project']
let g:gutentags_ctags_tagfile = '.tags'
let g:gutentags_cache_dir = expand('$vimroot/user/tmp/tags')
let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q']
let g:gutentags_ctags_extra_args += ['--c++-kinds=+px']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
let g:gutentags_modules = ['ctags', 'gtags_cscope']
let g:gutentags_plus_switch = 1
let g:gutentags_file_list_command = 'fd ".*\.[hc]$" .'
let g:gutentags_plus_nomap = 1

" easygrep
" let g:EasyGrepCommand=1
" set grepprg=rg\ --vimgrep
let g:EasyGrepMode=2
let g:EasyGrepReplaceWindowMode=2
let g:EasyGrepJumpToMatch=0
let g:EasyGrepAllOptionsInExplorer=1
let g:EasyGrepRoot="search:.root"

" ack - support rg
if executable('rg') | let g:ackprg = 'rg --vimgrep' | endif
let g:ackhighlight = 1
"let g:ack_qhandler = "botright copen 15"
"let g:ack_autoclose = 1
"let g:ack_use_cword_for_empty_search = 1

" LeaderF
let g:Lf_StlSeparator = { 'left': '', 'right': '', 'font': '' }
let g:Lf_RootMarkers = ['.project', '.root']
let g:Lf_WorkingDirectoryMode = 'Ac'
let g:Lf_WindowHeight = 0.30
let g:Lf_CacheDirectory = expand('$vimroot/user/tmp/lfcache')
let g:Lf_ShowRelativePath = 0
let g:Lf_HideHelp = 1
let g:Lf_MruMaxFiles = 1000
let g:Lf_StlColorscheme = 'default'
let g:Lf_PreviewResult = {'Function':0, 'BufTag':0}
let g:Lf_WindowPosition = 'popup'  " for vim 8.1.1615+
let g:Lf_PreviewInPopup = 1  " for vim 8.1.1615+
let g:Lf_ShowDevIcons = 1
" c-b will conflict with tmux
let g:Lf_StlPalette = {
            \'stlName':         { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'bold', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlCategory':     { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlNameOnlyMode': { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlFullPathMode': { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlFuzzyMode':    { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlRegexMode':    { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlCwd':          { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlBlank':        { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlLineInfo':     { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' },
            \'stlTotal':        { 'gui': 'NONE', 'font': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE', 'cterm': 'NONE', 'ctermfg': '0', 'ctermbg': '15' }
            \}
" netrw
let g:netrw_liststyle = 3

" TODO  rainbow_parentheses
" au VimEnter * RainbowParenthesesToggle
" au Syntax * RainbowParenthesesLoadRound
" au Syntax * RainbowParenthesesLoadSquare
" au Syntax * RainbowParenthesesLoadBraces

" Tabular  a for align
nmap <space>a= :Tabularize /=<CR>
vmap <space>a= :Tabularize /=<CR>
nmap <space>a: :Tabularize /:\zs<CR>
vmap <space>a: :Tabularize /:\zs<CR>
inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a

function! s:align()
    let p = '^ \s *| \s .* \s | \s *$'
    if exists( ':Tabularize' ) && getline( '.' ) =~# '^ \s *|' && (getline(line( '.' )-1) =~# p || getline(line( '. ' )+1) =~# p)
        let column = strlen(substitute(getline( '.' )[0:col( '.' )], '[^|]' , '' , 'g' ))
        let position = strlen(matchstr(getline( '.' )[0:col( '.' )], '.*| \s * \z s.*' ))
        Tabularize/|/l1
        normal! 0
        call search(repeat( '[^|]*|' ,column). ' \s \{ - \} ' .repeat( '.' ,position), 'ce' ,line( '.' ))
    endif
endfunction

" goyo
let g:goyo_width=120

" TODO Dirvish
let g:loaded_netrwPlugin = 1
command! -nargs=? -complete=dir Explore Dirvish <args>
command! -nargs=? -complete=dir Sexplore belowright split | silent Dirvish <args>
command! -nargs=? -complete=dir Vexplore leftabove vsplit | silent Dirvish <args>

" floaterm
let g:floaterm_title = "Terminal ($1|$2)"

let g:matchup_matchparen_offscreen = {'method': 'popup'}
let g:AutoPairsFlyMode = 1
let g:asyncrun_open = 6


" TODO
" let g:asyncrun_status = ''
" let g:airline_section_error = airline#section#create_right(['%{g:asyncrun_status}'])

function! s:lf_task_source(...)
	let rows = asynctasks#source(&columns * 48 / 100)
	let source = []
	for row in rows
		let name = row[0]
		let source += [name . '  ' . row[1] . '  : ' . row[2]]
	endfor
	return source
endfunction

function! s:lf_task_accept(line, arg)
	let pos = stridx(a:line, '<')
	if pos < 0
		return
	endif
	let name = strpart(a:line, 0, pos)
	let name = substitute(name, '^\s*\(.\{-}\)\s*$', '\1', '')
	if name != ''
		exec "AsyncTask " . name
	endif
endfunction

function! s:lf_task_digest(line, mode)
	let pos = stridx(a:line, '<')
	if pos < 0
		return [a:line, 0]
	endif
	let name = strpart(a:line, 0, pos)
	return [name, 0]
endfunction

function! s:lf_win_init(...)
	setlocal nonumber
	setlocal nowrap
endfunction

let g:Lf_Extensions = get(g:, 'Lf_Extensions', {})
let g:Lf_Extensions.task = {
			\ 'source': string(function('s:lf_task_source'))[10:-3],
			\ 'accept': string(function('s:lf_task_accept'))[10:-3],
			\ 'get_digest': string(function('s:lf_task_digest'))[10:-3],
			\ 'highlights_def': {
			\     'Lf_hl_funcScope': '^\S\+',
			\     'Lf_hl_funcDirname': '^\S\+\s*\zs<.*>\ze\s*:',
			\ },
			\ 'help' : 'navigate available tasks from asynctasks.vim',
		\ }


" fzf view
let g:coc_fzf_preview = ''
let g:coc_fzf_opts = []

let g:fff#split = "30vnew"
let g:fff#split_direction = "nosplitbelow nosplitright"


" How each level is indented and what to prepend.
" This could make the display more compact or more spacious.
" e.g., more compact: ["▸ ", ""]
" Note: this option only works for the kind renderer, not the tree renderer.
let g:vista_icon_indent = ["╰─▸ ", "├─▸ "]

" Executive used when opening vista sidebar without specifying it.
" See all the avaliable executives via `:echo g:vista#executives`.
let g:vista_default_executive = 'ctags'

" Set the executive for some filetypes explicitly. Use the explicit executive
" instead of the default one for these filetypes when using `:Vista` without
" specifying the executive.
let g:vista_executive_for = {
  \ 'cpp': 'vim_lsp',
  \ 'php': 'vim_lsp',
  \ }

" Declare the command including the executable and options used to generate ctags output
" for some certain filetypes.The file path will be appened to your custom command.
" For example:
let g:vista_ctags_cmd = {
      \ 'haskell': 'hasktags -x -o - -c',
      \ }

" To enable fzf's preview window set g:vista_fzf_preview.
" The elements of g:vista_fzf_preview will be passed as arguments to fzf#vim#with_preview()
" For example:
let g:vista_fzf_preview = ['right:50%']
" Ensure you have installed some decent font to show these pretty symbols, then you can enable icon for the kind.
let g:vista#renderer#enable_icon = 1

" The default icons can't be suitable for all the filetypes, you can extend it as you wish.
let g:vista#renderer#icons = {
\   "function": "\uf794",
\   "variable": "\uf71b",
\  }

" dotfiles provider
" TODO
let g:clap_provider_dotfiles = {
      \ 'source': ['~/.local/etc/config.sh', '~/.bashrc', '~/.local/etc/tmux/tmux.conf'],
      \ 'sink': 'e',
      \ }

let g:clap_popup_border = 'sharp'

" map normal-mode 's' for simple search
nmap s <Plug>(smalls)
" if you want to use smalls in visual/operator or both mode.
omap s <Plug>(smalls)
xmap s <Plug>(smalls)

" [NOTE] optionally it might be comfortable if you enable 'smartcase'
" comment-in following line if you want to.
" set ignorecase smartcase
"
" use double <ESC> to escape from terminal buffers, TODO
" tnoremap <silent> <C-[><C-[> <C-\><C-n>

" for fzf
autocmd! FileType fzf tnoremap <buffer> <esc> <c-c>

" for term
autocmd! FileType floaterm tnoremap <buffer> <esc> <nop>

let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.8 } }

" for vim-go
let $FZF_DEFAULT_OPTS = '--layout=reverse  --bind ctrl-p:abort'
let g:go_decls_mode = 'fzf'

let g:asynctasks_extra_config = [
    \ expand('$vimroot/user/vimrc/tasks.ini'),
    \ ]

